import { ModernBaseService } from './base/ModernBaseService';
import { Item, DataEquip, DataSkill } from '../shared/face';
import { ItemType, quality, qualityName } from '../shared/face/enums';
import { killLog } from '../core/rpg/types';
import enemy from '../core/rpg/entity/enemy';
import { ComType } from '../core/tool/component';
import dieReward_component from '../component/dieReward_component';
import { Icard2 } from '../core/tool/Icard2';
import { EquipService } from './EquipService';
import SkillManager from '../core/rpg/skill/SkManager';
import { BaseBody } from '../core/rpg/entity/body_base';
import Counter, { CounterKey } from '../core/manage/Counter';
import { PropRepository } from '../repository/PropRepository';

type CreatePropInput = {
    type: ItemType;
    id: string;
    count: number;
};

/**
 * ModernPropService
 * 道具与装备的创建、转换与奖励结算服务
 */
export class ModernPropService extends ModernBaseService {
    private get propRepository(): PropRepository {
        return this.getService<PropRepository>('PropRepository');
    }

    /**
     * 创建道具
     */
    createProp(input: CreatePropInput): Item {
        const item: Item = this.createEmptyItem();
        item.count = input.count;

        switch (input.type) {
            case ItemType.道具: {
                const cfg = this.config.get(this.configKey.道具表)?.get(input.id);
                if (!cfg) throw new Error(`道具配置不存在 ${input.id}`);
                item.id = cfg.id;
                item.type = ItemType.道具;
                item.quality = cfg.quality ?? quality.F;
                item.name = cfg.name;
                item.desc = cfg.desc;
                item.emoji = cfg.emoji;
                item.data = cfg.data ?? {};
                item.stacking = true;
                break;
            }
            case ItemType.装备: {
                // 模板来自 EquipManage；保持兼容
                const EquipManage = require('../core/manage/EquipManage').default;
                let template = EquipManage.getTemplateById(input.id);
                if (!template) {
                    template = EquipManage.getRandomTemplate();
                    if (!template) throw new Error('没有可用的装备模板，无法创建装备');
                }
                item.type = ItemType.装备;
                item.name = template.name;
                item.desc = template.desc;
                item.count = 1;
                item.data = this.createEquip(template);
                item.id = (item.data as DataEquip).id;
                item.quality = (item.data as DataEquip).quality;
                item.emoji = template.emoji;
                item.icon = template.icon;
                item.stacking = false;
                break;
            }
            case ItemType.资源: {
                const cfg = this.config.get(this.configKey.资源表)?.get(input.id);
                if (!cfg) throw new Error(`资源配置不存在 ${input.id}`);
                item.quality = quality.F;
                item.id = cfg.id;
                item.type = ItemType.资源;
                item.name = cfg.name;
                item.desc = cfg.desc;
                item.emoji = cfg.emoji;
                item.stacking = true;
                break;
            }
            case ItemType.消耗品: {
                const cfg = this.config.get(this.configKey.消耗品表)?.get(input.id);
                if (!cfg) throw new Error(`消耗品配置不存在 ${input.id}`);
                item.id = cfg.id;
                item.type = ItemType.消耗品;
                item.tag = cfg.tag;
                item.stacking = !!cfg.stacking;
                item.stacking_use = !!cfg.stackingUse;
                item.name = cfg.name;
                item.desc = cfg.desc;
                item.emoji = cfg.emoji;
                item.quality = cfg.quality ?? quality.F;
                item.data = { funcName: cfg.funcName, funcData: cfg.funcData };
                break;
            }
            default:
                throw new Error(`未知的道具类型 ${input.type}`);
        }

        return item;
    }

    /**
     * 自定义创建道具（直接使用外部提供的数据）
     */
    createPropCustomize(source: Item): Item {
        const item: Item = { ...source };
        item.uuid = this.sdk.tool.common.uuid;
        return item;
    }

    /**
     * 兼容别名：createProp_customize → createPropCustomize
     */
    createProp_customize(source: Item): Item {
        return this.createPropCustomize(source);
    }

    /**
     * 将装备转换为普通道具表示
     */
    coverEquipToItem(equip: DataEquip): Item {
        return {
            quality: equip.quality,
            uuid: this.sdk.tool.common.uuid,
            emoji: equip.emoji,
            id: equip.id,
            stacking: false,
            stacking_use: false,
            tag: '装备',
            name: equip.name,
            desc: equip.desc,
            type: ItemType.装备,
            count: 1,
            icon: '',
            data: equip
        } as Item;
    }

    /**
     * 兼容别名：cover_equipToItem → coverEquipToItem
     */
    cover_equipToItem(equip: DataEquip): Item {
        return this.coverEquipToItem(equip);
    }

    /**
     * V2查看道具/装备（与旧实现等价）
     */
    client_lookitemV2(item: Item, _card?: Icard2) {
        const card = _card || this.sdk.tool.card.create2();
        switch (item.type) {
            case ItemType.装备: {
                this.client_equip(item.data as DataEquip, card);
                break;
            }
            case ItemType.道具: {
                card.icon(item.emoji, item.icon);
                card.l('名称', item.name);
                card.l('描述', item.desc);
                break;
            }
            case ItemType.消耗品: {
                card.icon(item.emoji, item.icon);
                card.l('名称', item.name);
                card.l('类型', String(item.tag));
                card.l('品质', String((qualityName as any)[item.quality]));
                card.l('描述', item.desc);
                break;
            }
            default:
                return card;
        }
        return card;
    }

    /**
     * V2查看装备（与旧实现等价）
     */
    client_equip(equip: DataEquip, card: Icard2) {
        const equipService = this.getService<EquipService>('EquipService');
        card.icon(equip.emoji, equip.icon);
        card.l('编号', `#${equip.id}#UID${equip.creator}(${this.sdk.user.getNameByUid(equip.creator)})`);
        card.l('名称', `${equip.name} +${equip.strengthenLevel}`);
        card.l('品质', String((qualityName as any)[equip.quality]));
        card.l('体系', `${equip.sys}-${equip.type}-${equip.job}`);
        card.l('装备类型', `${equip.solt_type}`);

        let attributesText = '';
        equip.attribute.forEach((attr: any) => {
            if (equip.strengthenLevel > 1) {
                attributesText += `${attr.key}:${attr.val} +${equipService.getStrengthenMultiplier(equip.strengthenLevel)}\n`;
            } else {
                attributesText += `${attr.key}:${attr.val}\n`;
            }
        });
        card.l('属性', attributesText);

        if (equip.skill.length > 0) {
            let skillStr = '';
            equip.skill.forEach((item: DataSkill) => {
                const skill = SkillManager.getSkillById(item.skillId);
                if (skill) {
                    skillStr += `Lv.${item.level} ${item.reName || skill.name}\n`;
                }
            });
            card.l('技能', skillStr);
        }
        card.l('来源', equip.source);
        card.l('描述', equip.desc);
    }

    /**
     * V2查看血统（与旧实现等价）
     */
    client_talent(id: string, self: BaseBody | undefined, card: Icard2, Preview: boolean = true) {
        const cfg = this.config.get(this.configKey.配置_血统)?.get(id);
        card.icon(cfg.emoji, cfg.icon);
        card.l('体系', cfg.sys);
        if (!Preview && self) {
            const com_talent = (self as any).getComponent?.(ComType.血统);
            const item = com_talent?.getItem ? com_talent.getItem(id) : undefined;
            if (item) {
                let leve = '';
                const table: string[] = cfg.table.split('\n');
                if (cfg.leve == table.length) {
                    leve = '已满级';
                } else {
                    leve = String(item.level);
                }
                card.l('等级', leve);
                card.l('经验', `${item.exp_now}/${item.exp_max}`);
                card.l('称号', table[item.level - 1]);
                card.l('品质', String((qualityName as any)[item.quality]));
            }
            card.l('描述', cfg.desc);
        } else {
            card.l('名称', cfg.name);
            card.l('品质', String((qualityName as any)[quality.SSR]));
            card.l('描述', `使用将获得F级·${cfg.name}血统,如拥有血统,则获少量血统经验(有低概率提升血统品质)。`);
        }
        let att = '';
        cfg.attribute.forEach((a: any) => { att += `${a.key}:${a.val}\n`; });
        card.l('加成', att);
    }
    /**
     * 获取道具市场日志Key（与旧实现保持一致）
     */
    getItemMarketLogKey(data: Item): string {
        let key = `${data.type}-`;
        switch (data.type) {
            case ItemType.装备:
                key += data.name;
                break;
            case ItemType.资源:
                key += data.id;
                break;
            default:
                key = `${data.type}-${data.id}`;
                break;
        }
        return key;
    }

    /**
     * 盲盒奖励（与旧版行为等价，权重抽取）
     */
    coverBoxGift(data: any | any[], count: number = 1): Item[] {
        const cfg: any[] = Array.isArray(data) ? (data || []) : (data ? [data] : []);
        if (cfg.length === 0 || count < 1) return [];

        const weightOptions: Array<any & { start: number; end: number; weight: number }> = [];
        let totalWeight = 0;
        for (const item of cfg) {
            if (!item?.id) continue;
            const weight = Number(item.weight) || 0;
            if (weight > 0) {
                weightOptions.push({
                    ...item,
                    weight,
                    start: totalWeight,
                    end: totalWeight + weight
                });
                totalWeight += weight;
            }
        }

        if (totalWeight <= 0) return [];

        const randomValues = Array.from({ length: count }, () => this.sdk.tool.common.random(0, totalWeight));
        const result: Item[] = [];
        randomValues.forEach(randomVal => {
            const selected = weightOptions.find(opt => randomVal >= opt.start && randomVal < opt.end);
            if (!selected) return;
            const id = selected.func == 'eval' ? eval(selected.id) : selected.id;
            const max = selected.func == 'eval' ? eval(selected.max) : Number(selected.max);
            const min = selected.func == 'eval' ? eval(selected.min) : Number(selected.min);
            const prop = this.createProp({
                type: selected.type,
                id: id?.toString?.() ?? String(id),
                count: Math.ceil(this.sdk.tool.common.random(min, max))
            });
            result.push(prop);
        });

        return result;
    }

    /**
     * 按策略结算击杀奖励（兼容旧版行为）
     */
    PolicyReward_击杀(policy: string, log: killLog, mapId?: string): Item[] {
        const reward: Item[] = [];

        try {
            // 通用击杀奖励
            const commonCfg = this.config.get(`${this.configKey.通用击杀奖励}_通用击杀`) as Map<string, any>;
            const commonItem = commonCfg?.get(policy);
            if (commonItem) {
                reward.push(...this.coverEval(commonItem.rewardEval, log, mapId));
                reward.push(...this.coverFix(commonItem.rewardFix, mapId));
            }

            // 敌人死亡掉落
            if (log?.target?.getBody && log.target.getBody() instanceof enemy) {
                const dieCom = log.target.getComponent(ComType.死亡掉落) as dieReward_component;
                if (dieCom) {
                    const dieCfg = this.config.get(dieCom.cfg_table) as Map<string, any>;
                    const dieItem = dieCfg?.get(dieCom.cfg_id);
                    if (dieItem) {
                        reward.push(...this.coverEval(dieItem.rewardEval, log, mapId));
                        reward.push(...this.coverFix(dieItem.rewardFix, mapId));
                    }
                }
            }

            // 地图特定奖励
            if (mapId) {
                const mapCfg = this.config.get(`${this.configKey.通用击杀奖励}_地图_${mapId}`) as Map<string, any>;
                const mapItem = mapCfg?.get(policy);
                if (mapItem) {
                    reward.push(...this.coverEval(mapItem.rewardEval, log, mapId));
                    reward.push(...this.coverFix(mapItem.rewardFix, mapId));
                }
            }
        } catch (error: any) {
            this.log(`PolicyReward_击杀 error: ${error?.message || error}`, 'error');
        }

        return reward;
    }

    /**
     * 将可计算的奖励表达式转为具体道具
     */
    private coverEval(data: any | any[], v: any, mapId?: string): Item[] {
        if (!data) return [];
        const cfg: any[] = Array.isArray(data) ? data : [data];
        const returnData: Item[] = [];

        cfg.forEach(item => {
            if (!item?.id) return;

            let max: number;
            let min: number;
            try {
                const killLog = v;
                const target = killLog?.target;
                const unit = killLog?.unit;
                const round = killLog?.round;
                max = eval(item.max);
                min = eval(item.min);
            } catch (error) {
                this.log(`coverEval - 表达式求值失败: min=${item?.min}, max=${item?.max}`, 'error');
                return;
            }

            let id: any = isNaN(Number(item.id)) ? item.id : Number(item.id);
            if (item.type == ItemType.装备 && mapId) {
                id = `${mapId}_${id}`;
            }

            try {
                const prop = this.createProp({
                    type: item.type,
                    id: id.toString(),
                    count: Math.ceil(this.sdk.tool.common.random(min, max))
                });
                returnData.push(prop);
            } catch (error: any) {
                this.log(`coverEval - 创建道具失败: ${error?.message || error}`, 'error');
            }
        });

        return returnData;
    }

    /**
     * 将固定奖励配置转为具体道具
     */
    private coverFix(data: any | any[], mapId?: string): Item[] {
        if (!data) return [];
        const cfg: any[] = Array.isArray(data) ? data : [data];
        const returnData: Item[] = [];

        cfg.forEach(item => {
            if (!item?.id) return;
            const max = Number(item.max);
            const min = Number(item.min);
            let id: any = item.id;
            if (item.type == ItemType.装备 && mapId) {
                id = `${mapId}_${id}`;
            }

            try {
                const prop = this.createProp({
                    type: item.type,
                    id: String(id),
                    count: Math.ceil(this.sdk.tool.common.random(min, max))
                });
                returnData.push(prop);
            } catch (error: any) {
                this.log(`coverFix - 创建道具失败: ${error?.message || error}`, 'error');
            }
        });

        return returnData;
    }

    /**
     * 生成装备属性
     */
    createEquipAttribute(sys: string, type: string, job: string, soltType: string, q: quality) {
        const table = this.config.get(this.configKey.配置_装备属性) as Map<string, any>;
        const list = Array.from(table?.values() ?? []).filter((x: any) => x.sys === sys && x.type === type && x.job === job && x.solt === soltType);
        if (list.length === 0) return [];
        const item = list[this.sdk.tool.common.random(0, list.length - 1)];
        const attributes: Array<{ key: string; val: number }> = [];

        const appendAttr = (attr: any) => {
            const base = Number(attr.val);
            const randomDelta = this.sdk.tool.common.random(base * q, base * (q + 1));
            const val = Math.ceil(this.gameCfg.baseLeve * (base + randomDelta));
            attributes.push({ key: attr.key, val });
        };

        if (Array.isArray(item.attribute) && item.attribute.length) {
            for (const attr of item.attribute) appendAttr(attr);
        } else if (item.attribute) {
            appendAttr(item.attribute);
        }
        return attributes;
    }

    /**
     * 创建装备数据
     */
    private createEquip(template: any): DataEquip {
        const data: DataEquip = {
            uuid: this.sdk.tool.common.uuid,
            strengthenLevel: 1,
            count: 1,
            id: Counter.get(CounterKey.装备ID),
            icon: template.icon || 'none',
            sys: template.sys || '默认体系',
            type: template.type || '默认类型',
            job: template.job || '默认职业',
            quality: Counter.getQuality(),
            emoji: template.emoji || '🎯',
            source: template.source || '默认',
            name: template.name || '测试装备',
            solt_type: template.solt_type || '测试位置',
            desc: template.desc || '测试描述',
            creator: template.creator || 'sys',
            attribute: [],
            skill: [],
            createTime: Date.now(),
            updateTime: Date.now()
        };

        data.attribute = this.createEquipAttribute(data.sys, data.type, data.job, data.solt_type, data.quality);
        return data;
    }

    /**
     * 创建空道具
     */
    private createEmptyItem(): Item {
        return {
            quality: quality.F,
            uuid: this.sdk.tool.common.uuid,
            emoji: '🙂',
            id: '',
            name: '',
            desc: '',
            type: ItemType.资源,
            count: 0,
            data: {},
            icon: this.gameCfg.defaultIcon
        } as Item;
    }
}

export default ModernPropService;


